package com.lau.dicttranslator.serializer;

import com.lau.dicttranslator.annotation.DictField;
import com.lau.dicttranslator.enums.DictType;
import com.lau.dicttranslator.service.DictService;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.lang.reflect.Field;
import java.util.Collection;
import java.util.Map;

/**
 * 对象序列化器
 * 支持嵌套对象内的字典字段翻译
 */
@Component
@Slf4j
public class DictObjectSerializer extends JsonSerializer<Object> {
    
    @Autowired
    private DictService dictService;
    
    @Override
    public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        if (value == null) {
            gen.writeNull();
            return;
        }
        
        if (isPrimitiveOrWrapper(value.getClass()) || value instanceof String) {
            // 基本类型直接序列化
            gen.writeObject(value);
            return;
        }
        
        if (value instanceof Collection) {
            // 集合类型
            serializeCollection((Collection<?>) value, gen, serializers);
            return;
        }
        
        if (value instanceof Map) {
            // Map类型
            serializeMap((Map<?, ?>) value, gen, serializers);
            return;
        }
        
        // 对象类型
        serializeObject(value, gen, serializers);
    }
    
    /**
     * 序列化对象
     */
    private void serializeObject(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        gen.writeStartObject();
        
        Class<?> clazz = value.getClass();
        Field[] fields = clazz.getDeclaredFields();
        
        for (Field field : fields) {
            field.setAccessible(true);
            try {
                Object fieldValue = field.get(value);
                String fieldName = field.getName();
                
                // 序列化原始字段
                gen.writeObjectField(fieldName, fieldValue);
                
                // 检查是否有字典注解
                DictField dictField = field.getAnnotation(DictField.class);
                if (dictField != null && fieldValue != null) {
                    String displayName = getDisplayName(fieldValue, dictField);
                    if (displayName != null) {
                        String nameField = fieldName + dictField.nameSuffix();
                        gen.writeStringField(nameField, displayName);
                    }
                }
                
            } catch (IllegalAccessException e) {
                log.error("访问字段失败: {}", field.getName(), e);
            }
        }
        
        gen.writeEndObject();
    }
    
    /**
     * 序列化集合
     */
    private void serializeCollection(Collection<?> collection, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        gen.writeStartArray();
        for (Object item : collection) {
            serialize(item, gen, serializers);
        }
        gen.writeEndArray();
    }
    
    /**
     * 序列化Map
     */
    private void serializeMap(Map<?, ?> map, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        gen.writeStartObject();
        for (Map.Entry<?, ?> entry : map.entrySet()) {
            gen.writeObjectField(String.valueOf(entry.getKey()), entry.getValue());
        }
        gen.writeEndObject();
    }
    
    /**
     * 获取显示名称
     */
    private String getDisplayName(Object value, DictField dictField) {
        try {
            String dictKey = String.valueOf(value);
            
            // 使用DictField注解中的缓存配置
            boolean enableCache = dictField.enableCache();
            long cacheExpire = dictField.cacheExpire();
            
            if (dictField.dictType() == DictType.DATABASE) {
                // 数据库字典翻译，使用动态缓存配置
                return dictService.getDictLabel(dictField.dictCode(), dictKey, enableCache, cacheExpire);
            } else if (dictField.dictType() == DictType.ENUM) {
                // 枚举字典翻译，使用动态缓存配置
                return dictService.getEnumLabel(dictField.dictCode(), dictKey, enableCache, cacheExpire);
            }
            
        } catch (Exception e) {
            log.error("字典翻译失败，value: {}, dictCode: {}", value, dictField.dictCode(), e);
        }
        
        return null;
    }
    
    /**
     * 判断是否为基本类型或包装类型
     */
    private boolean isPrimitiveOrWrapper(Class<?> clazz) {
        return clazz.isPrimitive() || 
               Number.class.isAssignableFrom(clazz) ||
               Boolean.class.equals(clazz) ||
               Character.class.equals(clazz);
    }
} 